package com.example.close_order.scheduler;

import com.example.close_order.service.OrderCloseService;
import org.redisson.api.RScheduledExecutorService;
import org.redisson.api.RedissonClient;
import org.redisson.api.annotation.RInject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Component
public class OrderCloseScheduler {
    
    private static final Logger logger = LoggerFactory.getLogger(OrderCloseScheduler.class);
    
    @Autowired
    private OrderCloseService orderCloseService;
    
    @Autowired
    private RedissonClient redissonClient;
    
    @Value("${order.close.timeout.minutes:30}")
    private int orderCloseTimeoutMinutes;
    
    /**
     * Redisson分布式定时任务 - 订单关闭延迟任务执行器
     */
    public static class OrderCloseTask implements Runnable {
        @RInject
        private RedissonClient redissonClient;
        
        private String orderNo;
        
        public OrderCloseTask() {
            // 默认构造函数
        }
        
        public OrderCloseTask(String orderNo) {
            this.orderNo = orderNo;
        }
        
        @Override
        public void run() {
            // 这个任务会在Redisson的分布式环境中执行
            // 实际订单关闭逻辑在OrderCloseService中实现
            logger.info("Redisson分布式定时任务开始执行订单关闭: {}", orderNo);
        }
        
        public String getOrderNo() {
            return orderNo;
        }
        
        public void setOrderNo(String orderNo) {
            this.orderNo = orderNo;
        }
    }
    
    /**
     * 兜底补偿机制 - 每天凌晨扫描超期未关闭的订单
     * 避免极端情况下的遗漏
     */
    @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行
    public void compensateCloseExpiredOrders() {
        logger.info("开始执行兜底补偿机制，扫描超期未关闭订单");
        
        try {
            int closedCount = orderCloseService.batchCloseExpiredOrders();
            logger.info("兜底补偿机制执行完成，成功关闭订单数量: {}", closedCount);
        } catch (Exception e) {
            logger.error("兜底补偿机制执行异常", e);
        }
    }
    
    /**
     * 定时健康检查 - 每30分钟检查一次系统状态
     */
    @Scheduled(cron = "0 */30 * * * ?")
    public void healthCheck() {
        logger.info("订单关闭系统健康检查 - 当前时间: {}", LocalDateTime.now());
        // 可以添加更多的健康检查逻辑
    }
    
    /**
     * 添加订单关闭延迟任务到Redisson分布式调度器
     */
    public void scheduleOrderClose(String orderNo, long delay, TimeUnit timeUnit) {
        try {
            RScheduledExecutorService executor = redissonClient.getExecutorService("orderCloseExecutor");
            OrderCloseTask task = new OrderCloseTask(orderNo);
            
            executor.schedule(task, delay, timeUnit);
            logger.info("已添加订单关闭延迟任务，订单号: {}, 延迟: {} {}", 
                    orderNo, delay, timeUnit.name().toLowerCase());
        } catch (Exception e) {
            logger.error("添加订单关闭延迟任务失败: {}", orderNo, e);
            // 失败时立即执行关闭，避免遗漏
            orderCloseService.closeOrder(orderNo);
        }
    }
    
    /**
     * 取消订单关闭任务
     */
    public boolean cancelOrderCloseTask(String orderNo) {
        try {
            RScheduledExecutorService executor = redissonClient.getExecutorService("orderCloseExecutor");
            // 实际项目中需要更复杂的任务取消逻辑
            logger.info("取消订单关闭任务: {}", orderNo);
            return true;
        } catch (Exception e) {
            logger.error("取消订单关闭任务失败: {}", orderNo, e);
            return false;
        }
    }
}